package com.lhl.netty.common;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;

public class NetMessage {
    private final static Logger logger = LoggerFactory.getLogger(NetMessage.class);
    private String start = "@#";
    private NetMessageType type;
    private Integer length;
    private String content;
    private JSONObject contentJSONObject; //content转化成的json对象,仅作为方便解析消息内容用

    public NetMessage(NetMessageType type, String content) {
        content = content==null?"":content;
        byte[] contentByte = new byte[0];
        try {
            contentByte = content.getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            logger.error(ExceptionUtil.getMessage(e));
        }
        this.length = contentByte.length;
        this.type=type;
        this.content = content;
    }

    public NetMessage(String start, NetMessageType type, int length, String content) {
        this.start = start;
        this.type = type;
        this.length = length;
        this.content = content;
    }

    public byte[] toBytes() throws UnsupportedEncodingException {
        byte[] startByte = this.start.getBytes();
        byte[] typeByte = intToByteArray(this.type.ordinal());
        byte[] contentByte = content.getBytes("UTF-8");
        this.length = contentByte.length;
        return byteMerger(byteMerger(byteMerger(startByte,typeByte),intToByteArray(this.length)),contentByte);
    }

    public String toString(){
        return "{start:"+this.start+",type:"+this.type.name()+",length:"+((this.length/1024)+"K"+(this.length%1024)+"B")+",content:"+this.content+"}";
    }

    public NetMessage decodeFromBytes(byte[] data){
        String start= new String(subBytes(data,0,2));
        Integer type = byteArrayToInt(subBytes(data,2,4));
        Integer length = byteArrayToInt(subBytes(data,6,4));
        String content = new String(subBytes(data,10,data.length-10));
        return new NetMessage(start, NetMessageType.values()[type],length,content);
    }
    
    public String getParam(String key){
    	try{
    		if(contentJSONObject==null&&StringUtils.isNotEmpty(content)){
                contentJSONObject = JSONObject.parseObject(content);
        	}
        	return contentJSONObject.getString(key);
    	}catch(Exception e){
    		
    	}
    	return null;
    }
    
    public Integer getParamInt(String key){
    	try{
    		if(contentJSONObject==null&& StringUtils.isNotEmpty(content)){
                contentJSONObject = JSONObject.parseObject(content);
        	}
        	return contentJSONObject.getInteger(key);
    	}catch(Exception e){
    		
    	}
    	return null;
    }
    
    public Boolean getParamBool(String key){
    	try{
    		if(contentJSONObject==null&&StringUtils.isNotEmpty(content)){
                contentJSONObject = JSONObject.parseObject(content);
        	}
        	return contentJSONObject.getBoolean(key);
    	}catch(Exception e){
    		
    	}
    	return null;
    }
    
    public JSONObject getParamObj(String key){
    	try{
    		if(contentJSONObject==null&&StringUtils.isNotEmpty(content)){
                contentJSONObject = JSONObject.parseObject(content);
        	}
        	return contentJSONObject.getJSONObject(key);
    	}catch(Exception e){
    		
    	}
    	return null;
    }
    
    public JSONArray getParamArray(String key){
    	try{
    		if(contentJSONObject==null&&StringUtils.isNotEmpty(content)){
                contentJSONObject = JSONObject.parseObject(content);
        	}
        	return contentJSONObject.getJSONArray(key);
    	}catch(Exception e){
    		
    	}
    	return null;
    }

    public String getStart() {
        return start;
    }

    public void setStart(String start) {
        this.start = start;
    }

    public NetMessageType getType() {
        return type;
    }

    public void setType(NetMessageType type) {
        this.type = type;
    }

    public Integer getLength() {
        return length;
    }

    public void setLength(Integer length) {
        this.length = length;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    /**
     * 将16位的short转换成byte数组 
     *  
     * @param s 
     *            short 
     * @return byte[] 长度为2 
     * */  
    private static byte[] shortToByteArray(short s) {  
        byte[] targets = new byte[2];  
        for (int i = 0; i < 2; i++) {  
            int offset = (targets.length - 1 - i) * 8;  
            targets[i] = (byte) ((s >>> offset) & 0xff);  
        }  
        return targets;  
    } 
    
    /** 
     * 注释：字节数组到short的转换！ 
     * 
     * @param b 
     * @return 
     */ 
    private static short bytesArrayToShort(byte[] b) { 
        short s = 0; 
        short s0 = (short) (b[0] & 0xff);// 最低位 
        short s1 = (short) (b[1] & 0xff); 
        s1 <<= 8; 
        s = (short) (s0 | s1); 
        return s; 
    }

    //byte 数组与 int 的相互转换
    private static int byteArrayToInt(byte[] b) {
        return   b[3] & 0xFF |
                (b[2] & 0xFF) << 8 |
                (b[1] & 0xFF) << 16 |
                (b[0] & 0xFF) << 24;
    }
    //byte 数组与 int 的相互转换
    private static byte[] intToByteArray(int a) {
        return new byte[] {
                (byte) ((a >> 24) & 0xFF),
                (byte) ((a >> 16) & 0xFF),
                (byte) ((a >> 8) & 0xFF),
                (byte) (a & 0xFF)
        };
    }

    //byte 数组合并
    private static byte[] byteMerger(byte[] byte_1, byte[] byte_2){
        byte[] byte_3 = new byte[byte_1.length+byte_2.length];
        System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length);
        System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length);
        return byte_3;
    }

    /**
     * 从一个byte[]数组中截取一部分
     * @param src
     * @param begin
     * @param count
     * @return
     */
    private static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        for (int i=begin; i<begin+count; i++) bs[i-begin] = src[i];
        return bs;
    }


    public static void main(String[] args){
        NetMessage msg  = new NetMessage(NetMessageType.MESSAGE_USER_INPUT,"fjdsalkjfldsajfldsajfldsajfldsaf");
        try {
            System.out.println(msg.decodeFromBytes(msg.toBytes()));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}
